package FCRendering.azer;

import FCRendering.FCRBattleOrderConstant;
import FCRendering.FCRMaster;
import Function.FCMapLibrary;
import Function.FCMutilPlayCache;
import Function.FCMutilPlayTankCache;
import VWorldGameStudio.*;
import VWorldGameStudio.events.DoorEvent;
import VWorldGameStudio.events.JumpEvent;
import socket.FCRSocketClient;
import socket.FCRSocketServer;
import utils.FCMixUtil;

import java.util.ArrayList;
import java.util.function.BiConsumer;

import static FCRendering.FCRMaster.*;

/**
 * @Description
 * @Author JingTingFeng
 * @Create 2021-05-30 12:04
 */
public class PlayerAction {
    // 系数
    public boolean changeHostId = false;
    private static final PlayerAction instance = new PlayerAction();
    private int stepRecord = 0;

    private PlayerAction() {
    }

    public static PlayerAction getInstance() {
        return instance;
    }


    /**
     * 增加修改返回是否有更改了偏移量，或者坐标等就要返回要同步一次否不用
     */
    public boolean playerAction() {
//        int fastSpeed = 80 + player1.getSpeed1() + player1.getSpeed2();
//        int vSpeedLevel = 16 - ((fastSpeed - 50) / 20) * 2;
//        vSpeedLevel = Math.min(vSpeedLevel, 16);
//        vSpeedLevel = Math.max(vSpeedLevel, 6);
        int vSpeedLevel = 6;
        int vPerStep = (int) (64 * fcv.getProportion() / vSpeedLevel);//表示一步走vPerStep个像素
        return moveAction(vPerStep, player1.getActionDir());
    }

    public void stepChangeAndCheckLongTermState() {
        if (gameSave.getQiXiPingBiSteps() > 0) {
            //TODO 这个是气息屏蔽器功能，多少步内，遇敌几率减低
            gameSave.setQiXiPingBiSteps(gameSave.getQiXiPingBiSteps() - 1);
            if (gameSave.getQiXiPingBiSteps() == 0) {
                gameSave.setYuGuaiJilv(80);
                fcv.getMessage().add("气息屏蔽已经失效");
                fcv.showMessage();
            }
        }

        //TODO 行走了，检查是否有毒气啊，麻痹啊之类的扣血，注意只计算本地队伍的，别的玩家的血量让他们自己算完同步血量过来就行了
        if (stepRecord == 0) {
            stepRecord = gameSave.getStepCount();
        } else if (gameSave.getStepCount() - stepRecord > 2) {//每动俩步
            FCLongTermState state = player1.getLongTermMap().get(FCRBattleOrderConstant.S_Acid);
            ArrayList<FCPlayerInfo> needSyncRemoteBlood = new ArrayList<>(0);
            FCTank drvTank = tankLib.getTankOfID(player1.getPlayertank1(), player1.getPlayertankHostId());
            if (state != null) {
                //TODO 酸
                int val = state.value;
                player1.subBlood(Math.max(5, (int) (val * (1f - (float) player1.getPlayerAcidDefend() / 100))));
                needSyncRemoteBlood.add(player1);
            }
            state = player1.getLongTermMap().get(FCRBattleOrderConstant.S_Gas);
            if (state != null) {
                //TODO 中毒
                int val = state.value;
                if (drvTank != null && (drvTank.isOpenKongTiao() || drvTank.isOpenQiShan())) {
                    val = (int) (val * 0.6);
                }
                player1.subBlood(Math.max(5, (int) (val * (1f - (float) player1.getPlayerGasDefend() / 100))));
                if (!needSyncRemoteBlood.contains(player1)) {
                    needSyncRemoteBlood.add(player1);
                }
            }
            if (player1.isDeath()) {
                //下车
                gameSave.useTankOfPlayerId(player1, player1.getPlayertank1(), player1.getPlayertankHostId());
            }

            //随机率获得鸟粪
            FCMixUtil.mayBeGetReduice(tankLib.getTankOfID(player1.getPlayertank1(), player1.getPlayertankHostId()));


            for (FCRPlayerLink fcrPlayerLink : FCMutilPlayCache.getTeamMembers()) {
                if (fcrPlayerLink.curPlayerHostUID.equals(gameSave.HOST_UID)) {
                    FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(fcrPlayerLink.curPlayerHostUID, fcrPlayerLink.curPlayerName);
                    if (p != null) {
                        int val = 0;
                        drvTank = tankLib.getTankOfID(p.getPlayertank1(), p.getPlayertankHostId());
                        state = p.getLongTermMap().get(FCRBattleOrderConstant.S_Acid);
                        if (state != null) {
                            //TODO 酸
                            val = state.value;
                            p.subBlood(Math.max(5, (int) (val * (1f - (float) player1.getPlayerAcidDefend() / 100))));
                            needSyncRemoteBlood.add(p);
                        }
                        state = p.getLongTermMap().get(FCRBattleOrderConstant.S_Gas);
                        if (state != null) {
                            val = state.value;
                            //TODO 中毒
                            if (drvTank != null && (drvTank.isOpenKongTiao() || drvTank.isOpenQiShan())) {
                                val = (int) (val * 0.6);
                            }
                            p.subBlood(Math.max(5, (int) (val * (1f - (float) player1.getPlayerGasDefend() / 100))));
                            if (!needSyncRemoteBlood.contains(p)) {
                                needSyncRemoteBlood.add(p);
                            }
                        }
                        if (p.isDeath()) {
                            gameSave.useTankOfPlayerId(p, p.getPlayertank1(), p.getPlayertankHostId());
                            //下车
                        }

                        //随机率获得鸟粪
                        FCMixUtil.mayBeGetReduice(tankLib.getTankOfID(p.getPlayertank1(), p.getPlayertankHostId()));
                    }
                }
            }
            stepRecord = gameSave.getStepCount();
            //TODO 同步给其他队友血量减少了,
            if (FCRMaster.fcv.isSever()) {
                FCRSocketServer.getIn().syncPlayerState(needSyncRemoteBlood);
            } else if (FCRMaster.fcv.isClient()) {
                FCRSocketClient.getIn().syncPlayerState(needSyncRemoteBlood);
            }

            //TODO 判断所有的战车，符合中酸的
            gameSave.getTankSaveIos().forEach(new BiConsumer<String, FCTank>() {
                @Override
                public void accept(String s, FCTank tank) {
                    FCMixUtil.stepCheckAcidAndSubDefense(tank);
                }
            });


            if (!fcv.isInTeamLink()) {
                //是否队长死了，
                if (player1.isDeath()) {
                    fcv.setPlayingEvent(eventLib.getEventOfName("WelcomeToMingQi"));
                    fcv.setJumpactionnum(0);
                    JumpEvent jumpEvent = (JumpEvent) fcv.getPlayingEvent();
                    sound.setEffectSound(jumpEvent.getMusicnum0());
                    //TODO 通知队友也要转场了
                    if (FCRMaster.fcv.isSever()) {
                        FCRSocketServer.getIn().playerJumpEvent(fcv.getPlayingEvent().getName(), jumpEvent.getDestination());
                    } else if (FCRMaster.fcv.isClient()) {
                        FCRSocketClient.getIn().playerJumpEvent(fcv.getPlayingEvent().getName(), jumpEvent.getDestination());
                    }

                    //TODO 送你去见明奇
                    FCRMaster.fcrMaster.startToSeeMingQi();
                }
            }
        }
    }

    public boolean moveAction(int vPerStep, int playerDir){
        if (changeHostId) {
            return false;
        }
        FCPlayerInfo player1 = FCRMaster.player1;
        FCSave gamesave = FCRMaster.gameSave;
        FCMapLibrary mapl = FCRMaster.mapLib;
        int offsetX = FCRMaster.player1.getPianYiX();
        int offsetY = FCRMaster.player1.getPianYiY();
        int playerX = FCRMaster.player1.getPlayer1x();
        int playerY = FCRMaster.player1.getPlayer1y();

        // 方向
        int up = 3;
        int right = 2;
        int down = 0;
        int left = 1;

        //判断队伍里是否有人驾驶坦克
        boolean hasDriverTankInTeam = false;
        boolean canTankGo = true;
        boolean allDie = true;
        if (!player1.getPlayertank1().equals("null")) {
            hasDriverTankInTeam = true;
            FCTank tank = tankLib.getTankOfID(player1.getPlayertank1(), player1.getPlayertankHostId());
            if (tank != null && !tank.canMove()) {
                canTankGo = false;
            }
        }
        if (!player1.isDeath()) allDie = false;

        if (canTankGo) {
            for (FCRPlayerLink fcrPlayerLink : FCMutilPlayCache.getTeamMembers()) {
                if (fcrPlayerLink.curPlayerHostUID.equals("npc") || fcrPlayerLink.curPlayerHostUID.equals(gamesave.HOST_UID)) {
                    FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(fcrPlayerLink.curPlayerHostUID, fcrPlayerLink.curPlayerName);
                    if (p == null) continue;
                    if (!p.isDeath()) {
                        allDie = false;
                    }
                    if (!p.getPlayertank1().equals("null")) {
                        //TODO 不要判断别的玩家的，能加进来就能走
                        hasDriverTankInTeam = true;
                        FCTank tank = tankLib.getTankOfID(p.getPlayertank1(), p.getPlayertankHostId());
                        if (tank != null && !tank.canMove()) {
                            canTankGo = false;
                        }
                    }
                }
            }
        }

        if (!canTankGo || allDie) {
            return false;
        }


        /**
         * 速度是按级别分的，比如是一个格子64像素只走8步为一个等级，走16步为一个等级，走4步为一个等级
         * 只有16,14,12,10,8,6这些等级
         * player1.getSpeed1() = 40 speed2（）驾驶等级 = 10 就是16格，
         *  设定fastSpeed = 50 就是16格，
         *  没加20速就下一个阶级14
         *vSpeedLevel = 16 - 2*(fastSpeed-50)/20;
         * fastSpeed = 100时， vSpeedLevel = 12
         */
        if (playerDir == down) {

            // 下一步区域
            int x = player1.getPlayer1CoorX() + 1;
            int y = player1.getPlayer1CoorY();

            //还有种情况，前面是墙,去不了
            String blockname = mapLib.getMapOfName(player1.getMapname())
                    .getPlaceNameOfCoor(x, y);
            if (blockname.startsWith("Men")) {
                //是门
                FCEvent mayBeDoor = eventLib.getEventOfName(mapLib.getMapOfName(player1.getMapname())
                        .getEventNameOfCoor(x, y));
                if (mayBeDoor instanceof DoorEvent) {
                    //是门，判断有没有钥匙吧,或者已经开过了，
                    if (!gameSave.getSaveAllHasUnLockDoors().contains(mayBeDoor.getName())) {
                        //TODO 这个门还没开过的
                        return false;
                    }
                }
            }

            // 判断下方是否存在NPC,此处的加1为下面一个格子
            boolean isExistNPC = FCRMaster.fcv.checkAndGetNpcInXYTag(x + "*" + y) != null;
            String key = player1.getMapname() + "*" + x + "*" + y;
            if (isExistNPC) {
                if (gamesave.getBattleBossMaps().containsKey(key) || gamesave.getOtherEventMaps().containsKey(key)) {
                    //TODO 哪就是这个npc是个boss，已经被打掉了,不会在显示了
                    isExistNPC = false;
                }
            }

            // 判断该地图区域是否可通过
            boolean isCanPass = true;
            if (!gamesave.getOtherEventMaps().containsKey(key)) {
                if (!hasDriverTankInTeam)
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 2;
                else
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 1;
            }

            if (!isExistNPC && isCanPass) {
                FCRMaster.player1.setPianYiYAndDispatchPianYI(offsetY + vPerStep);
            }
            if (player1.getPianYiY() >= 64 * FCRMaster.fcv.getProportion()) {
                player1.movePlayer1Coor(1, 0);
                FCRMaster.player1.setPianYiYAndDispatchPianYI(0);//队伍链的Y也要变更，
                FCRMaster.fcv.setOpenENMonster(true);
            }
        }

        if (playerDir == up) {

            // 下一步区域
            int x = player1.getPlayer1CoorX() - 1;
            int y = player1.getPlayer1CoorY();
            //还有种情况，前面是墙,去不了
            String blockname = mapLib.getMapOfName(player1.getMapname())
                    .getPlaceNameOfCoor(x, y);
            if (blockname.startsWith("Men")) {
                //是门
                FCEvent mayBeDoor = eventLib.getEventOfName(mapLib.getMapOfName(player1.getMapname())
                        .getEventNameOfCoor(x, y));
                if (mayBeDoor instanceof DoorEvent) {
                    //是门，判断有没有钥匙吧,或者已经开过了，
                    if (!gameSave.getSaveAllHasUnLockDoors().contains(mayBeDoor.getName())) {
                        //TODO 这个门还没开过的
                        return false;
                    }
                }
            }

            String key = player1.getMapname() + "*" + x + "*" + y;
            // 判断上方是否存在NPC
            boolean isExistNPC = FCRMaster.fcv.checkAndGetNpcInXYTag(x + "*" + y) != null;
            if (isExistNPC) {
                if (gamesave.getBattleBossMaps().containsKey(key) || gamesave.getOtherEventMaps().containsKey(key)) {
                    //TODO 哪就是这个npc是个boss，已经被打掉了,不会在显示了
                    isExistNPC = false;
                }
            }

            // 判断该地图区域是否可通过
            boolean isCanPass = true;
            if (!gamesave.getOtherEventMaps().containsKey(key)) {
                if (!hasDriverTankInTeam)
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 2;
                else
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 1;
            }

            // offsetY 偏移修正
            if (!isExistNPC && isCanPass) {
                FCRMaster.player1.setPianYiYAndDispatchPianYI(offsetY - vPerStep);
            }
            if (player1.getPianYiY() <= -(int) (64 * FCRMaster.fcv.getProportion())) {
                player1.movePlayer1Coor(-1, 0);
                FCRMaster.player1.setPianYiYAndDispatchPianYI(0);
                FCRMaster.fcv.setOpenENMonster(true);
            }

        }

        if (playerDir == left) {

            // 下一步区域
            int x = player1.getPlayer1CoorX();
            int y = player1.getPlayer1CoorY() - 1;
            String key = player1.getMapname() + "*" + x + "*" + y;
            // 判断左方是否存在NPC
            boolean isExistNPC = FCRMaster.fcv.checkAndGetNpcInXYTag(x + "*" + y) != null;
            if (isExistNPC) {
                if (gamesave.getBattleBossMaps().containsKey(key) || gamesave.getOtherEventMaps().containsKey(key)) {
                    //TODO 哪就是这个npc是个boss，已经被打掉了,不会在显示了
                    isExistNPC = false;
                }
            }
            // 判断该地图区域是否可通过
            boolean isCanPass = true;
            if (!gamesave.getOtherEventMaps().containsKey(key)) {
                if (!hasDriverTankInTeam)
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 2;
                else
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 1;
            }

            // offsetX 偏移修正
            if (!isExistNPC && isCanPass) {
                FCRMaster.player1.setPianYiXAndDispatchPianYI(offsetX - vPerStep);
            }
            if (player1.getPianYiX() <= -(int) (64 * FCRMaster.fcv.getProportion())) {
                player1.movePlayer1Coor(0, -1);
                FCRMaster.player1.setPianYiXAndDispatchPianYI(0);
                FCRMaster.fcv.setOpenENMonster(true);
            }
        }

        if (playerDir == right) {

            // 下一步区域
            int x = player1.getPlayer1CoorX();
            int y = player1.getPlayer1CoorY() + 1;
            String key = player1.getMapname() + "*" + x + "*" + y;
            // 判断右方是否存在NPC
            boolean isExistNPC = FCRMaster.fcv.checkAndGetNpcInXYTag(x + "*" + y) != null;
            if (isExistNPC) {
                if (gamesave.getBattleBossMaps().containsKey(key) || gamesave.getOtherEventMaps().containsKey(key)) {
                    //TODO 哪就是这个npc是个boss，已经被打掉了,不会在显示了
                    isExistNPC = false;
                }
            }

            // 判断该地图区域是否可通过
            boolean isCanPass = true;
            if (!gamesave.getOtherEventMaps().containsKey(key)) {
                if (!hasDriverTankInTeam)
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 2;
                else
                    isCanPass = mapl.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x, y) < 1;
            }

            // offsetX 偏移修正
            if (!isExistNPC && isCanPass) {
                FCRMaster.player1.setPianYiXAndDispatchPianYI(offsetX + vPerStep);
            }
            if (player1.getPianYiX() >= (int) (64 * FCRMaster.fcv.getProportion())) {
                player1.movePlayer1Coor(0, 1);
                FCRMaster.player1.setPianYiXAndDispatchPianYI(0);
                FCRMaster.fcv.setOpenENMonster(true);
            }
        }

        if (playerX != player1.getPlayer1x() || playerY != player1.getPlayer1y()) {
            gamesave.addStepCount();//计算增加步数
            stepChangeAndCheckLongTermState();
            //有走动就消除显示
            if (!fcv.isInTeamLink()) {
                fcv.closeAllShowWindw();
            }
        }
        //有更改就触发
        if (offsetX != player1.getPianYiX() || offsetY != player1.getPianYiY() || playerX != player1.getPlayer1x() || playerY != player1.getPlayer1y()) {
            return true;
        } else {
            return false;
        }
    }

    //直接向前滑动指定方向的
    public boolean slideAction(int dir){
        int fastSpeed = 80 + player1.getSpeed1() + player1.getSpeed2();
        int vSpeedLevel = 16 - ((fastSpeed - 50) / 20) * 2;
        vSpeedLevel = Math.min(vSpeedLevel, 16);
        vSpeedLevel = Math.max(vSpeedLevel, 6);
        vSpeedLevel = 4;
        int vPerStep = (int) (64 * fcv.getProportion() / vSpeedLevel);//表示一步走vPerStep个像素
        return moveAction(vPerStep, dir);
    }

}
